package com.alibaba.user.service.impl;

import com.alibaba.api.dtos.RequestDTO;
import com.alibaba.api.dtos.ResponseResult;
import com.alibaba.user.mapper.UserMapper;
import com.alibaba.user.pojos.User;
import com.alibaba.user.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.lang3.RandomUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.time.Duration;
import java.util.*;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public ResponseResult register(RequestDTO requestDTO) {
        //参数检查
        String phone = requestDTO.getPhone();
        String code = requestDTO.getCode();

        if(null == requestDTO || null == code || null == phone)
            return new ResponseResult(300,"无效参数");

        if (!redisTemplate.hasKey(phone))
            return new ResponseResult(400,"验证码不存在");

        if (!code.equals(redisTemplate.opsForValue().get(phone)))
            return new ResponseResult(401,"验证码不正确");

        User user = new User();
        user.setUsername(requestDTO.getName());
        user.setPassword(DigestUtils.md5DigestAsHex(requestDTO.getPassword().getBytes()));
        user.setPhone(requestDTO.getPhone());
        user.setCreateTime(new Date());
        user.setAccountId(RandomUtils.nextInt(100000000,999999999));
        //保存用户
        save(user);

        //删除key
        redisTemplate.delete(phone);
        return new ResponseResult(200, "ok");
    }

    @Override
    public ResponseResult login(String phone, String code) {
        if (null == phone || null == code) {
            return new ResponseResult(300,"无效参数");
        }

        if (!redisTemplate.hasKey(phone))
            return new ResponseResult(400,"验证码不存在");

        if (!code.equals(redisTemplate.opsForValue().get(phone)))
            return new ResponseResult(401,"验证码不正确");

        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("phone", phone);
        User user = getOne(wrapper);
        String token = getToken(user.getId());
        Map map = new HashMap<>();
        map.put("token", token);
        //结果集封装
        return new ResponseResult(200, "ok", map);
    }

    public String getToken(Integer id) {
        User user = getById(id);
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", id);
        claims.put("accountId", user.getAccountId());
        String token = Jwts.builder()
                .setClaims(claims)
                .signWith(SignatureAlgorithm.HS256, "secret")
                .setExpiration(new DateTime().plusHours(12).toDate())
                .compact();
        return token;
    }

    @Override
    public ResponseResult code(String phone) {
        if (null == phone) {
            return new ResponseResult(300,"无效参数");
        }

        if (redisTemplate.hasKey(phone))
            return new ResponseResult(400,"已经发生过验证码");

        Integer code = RandomUtils.nextInt(100000, 999999);
        redisTemplate.opsForValue().set(phone, code.toString(), Duration.ofMinutes(5));

        Map map = new HashMap();
        map.put("code", code);

        return new ResponseResult(200, "ok", map);
    }
}
